import {JSXAttributes, useElement} from './core/element.js';
import {Theme} from './page.js';

const name = 's-search';
const props = {
    placeholder: '',
    disable: false,
    value: '',
    maxLength: -1,
    readOnly: false
};

const style = () => `
:host {
    --container-height: 40px;
    display: inline-flex;
    vertical-align: middle;
    width: 220px;
    height: var(--container-height);
    color: var(--s-color-on-surface, ${Theme.colorOnSurface});
    background: var(--s-color-surface-container-high, ${Theme.colorSurfaceContainerHigh});
    border-radius: 24px;
    font-size: .875rem;
    flex-shrink: 0;
    position: relative;
}

.container {
    box-sizing: border-box;
    height: 100%;
    padding: 0 0.75rem;
    display: flex;
    gap: 0.25rem;
    flex-grow: 1;
    position: relative;
    align-items: center;
}

.container .start {
    width: 24px;
    height: 24px;
}

:host(:focus-within) .container {
    z-index: var(--z-index, 1);
}

input {
    flex: 1;
    border: none;
    width: 100%;
    margin: 0;
    padding: 0;
    height: var(--container-height);
    line-height: var(--container-height);
    background: none;
    outline: none;
    font-size: inherit;
    color: inherit;
    box-sizing: border-box;
    font-family: inherit;
    caret-color: var(--s-color-primary, ${Theme.colorPrimary});
}

input::placeholder {
    color: var(--s-color-outline, ${Theme.colorOutline});
}

input::selection {
    background: var(--s-color-primary, ${Theme.colorPrimary});
    color: var(--s-color-on-primary, ${Theme.colorOnPrimary});
}

.dropdown {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    pointer-events: none;
    background: inherit;
    box-shadow: var(--s-elevation-level2, ${Theme.elevationLevel2});
    opacity: 0;
    border-radius: 4px;
    transition: opacity .2s ease-out;
}

:host(:focus-within) .dropdown {
    opacity: 1;
    pointer-events: auto;
    z-index: var(--z-index, 1);
}

::slotted([slot=dropdown]) {
    margin-top: var(--container-height);
    border-radius: 4px;
    border-top: solid 1px var(--s-color-outline-variant, ${Theme.colorOutlineVariant});
}

::slotted([slot=start]),
::slotted([slot=end]) {
    flex-shrink: 0;
}
`;

const template = () => `
<div class="dropdown" part="dropdown">
    <slot name="dropdown"></slot>
</div>
<div class="container" part="container">
    <slot name="start"></slot>
    <input type="text">
    <slot name="end"></slot>
</div>
`;

export class Search extends useElement({
    style: style(),
    template: template(),
    props,
    syncProps: ['disable', 'readOnly'],
    setup(shadowRoot) {
        const input = shadowRoot.querySelector('input') as HTMLInputElement;
        const dropdown = shadowRoot.querySelector('[name=dropdown]') as HTMLSlotElement;
        dropdown.addEventListener('mousedown', (e) => e.preventDefault());
        input.addEventListener('change', () => this.dispatchEvent(new Event('change')));
        return {
            expose: {
                get value() {
                    return input.value;
                }
            },
            props: {
                value: (value) => input.value = value,
                placeholder: (placeholder) => input.placeholder = placeholder,
                maxLength: (maxLength) => input.maxLength = maxLength,
                readOnly: (readOnly) => input.readOnly = readOnly
            }
        };
    }
}) {
}

Search.define(name);

declare global {
    namespace JSX {
        interface IntrinsicElements {
            [name]: Partial<typeof props> & JSXAttributes;
        }
    }

    interface HTMLElementTagNameMap {
        [name]: Search;
    }
}

//@ts-ignore
declare module 'vue' {
    export interface GlobalComponents {
        [name]: typeof props;
    }
}
